package com.homedo.microservice.open.service.gateway.manager.web.gateway.service;

import com.google.common.collect.Lists;
import com.homedo.common.bean.data.enums.ResponseEnum;
import com.homedo.common.bean.vo.Pagination;
import com.homedo.common.bean.vo.context.UserContext;
import com.homedo.common.dao.bean.po.base.BasePo;
import com.homedo.common.exception.HomedoException;
import com.homedo.common.service.BaseService;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.constant.CommonConstant;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.po.Config;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.po.ConfigRelation;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.bean.po.enhanced.ConfigEnhanced;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.persistence.dao.ConfigDao;
import com.homedo.microservice.open.service.gateway.manager.web.gateway.persistence.dao.ConfigRelationDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 作者 jgshun
 * @date 创建时间 2018年09月11日 17时25分30秒
 */
@Service
public class ConfigService extends BaseService<Config> {
    @Autowired
    private ConfigDao configDao;
    @Autowired
    private ConfigRelationDao configRelationDao;


    @Override
    public List<ConfigEnhanced> getEnhanceds(List<?> ids, UserContext userContext) {
        List<Config> configs = configDao.getListByIds(ids, Config.class);

        if (!Detect.notEmpty(configs)) {
            return null;
        }

        return this.convent2Enhanceds(configs);
    }


    @Override
    public List<ConfigEnhanced> getEnhanceds4Active(List<?> ids, UserContext userContext) {
        List<Config> configs = configDao.getListByIdsGreaterThanMark0(ids, Config.class);

        if (!Detect.notEmpty(configs)) {
            return null;
        }

        return this.convent2Enhanceds(configs);
    }


    @Override
    public List<ConfigEnhanced> convent2Enhanceds(List<? extends BasePo> pos) {
        List<Config> configs = (List<Config>) pos;
        List<ConfigEnhanced> configEnhanceds = Lists.newArrayList();
        configs.forEach(e -> configEnhanceds.add(new ConfigEnhanced(e)));
        return configEnhanceds;
    }


    public ConfigEnhanced getEnhanceds4Application(String applicationName, String name, UserContext userContext) {
        List<ConfigEnhanced> configEnhanceds = this.getEnhanceds4Application(applicationName, Lists.newArrayList(name), userContext);
        if (!Detect.notEmpty(configEnhanceds)) {
            return null;
        }

        return configEnhanceds.get(0);
    }

    public List<ConfigEnhanced> getEnhanceds4Application(String applicationName, List<String> names, UserContext userContext) {
        List<Config> configs = configDao.getListByApplication(applicationName, names);
        if (!Detect.notEmpty(configs)) {
            return null;
        }
        return this.convent2Enhanceds(configs);
    }


    public Pagination<ConfigEnhanced> getPagination4Application(String applicationName, List<String> zuulFilterIds, Pagination<ConfigEnhanced> pagination, UserContext userContext) {
        List<String> configNames = null;

        List<ConfigRelation> configRelations = configRelationDao.getList(applicationName, zuulFilterIds);
        if (Detect.notEmpty(configRelations)) {
            configNames = configRelations.stream().map(ConfigRelation::getConfigName).collect(Collectors.toList());
        }

        if (!Detect.notEmpty(configNames)) {
            return pagination;
        }

        List<ConfigEnhanced> configEnhanceds = this.getEnhanceds4Application(applicationName, configNames, userContext);

        pagination.setItems(configEnhanceds);

        return pagination;
    }

    public void updateConfig(String applicationName, String name, String value, String comment, UserContext userContext) {
        this.checkUpdate(applicationName, name, comment);
        Config config = configDao.getListByApplication(applicationName, name);
        config.setValue(value);
        if (Detect.notEmpty(comment)) {
            config.setComment(comment);
        }
        config.setUpdateTime(new Date());

        configDao.updateByPrimaryKeySelective(config);
    }

    private void checkUpdate(String applicationName, String name, String comment) {
        if (!Detect.notEmpty(applicationName) || !Detect.notEmpty(name)) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
    }

    public Config addConfig(Config config, String zuulFilterId, UserContext userContext) {
        this.checkAdd(config, zuulFilterId);

        config.setCreateTime(new Date());
        config.setUpdateTime(new Date());

        config = configDao.saveSelective(config);

        ConfigRelation configRelation = new ConfigRelation();
        configRelation.setApplicationName(config.getApplicationName());
        configRelation.setZuulFilterId(zuulFilterId);
        configRelation.setConfigName(config.getName());
        configRelation.setGlobal(zuulFilterId.equals(CommonConstant.GLOBAL_CONFIG_RELATION_KEY));
        configRelation.setCreateTime(new Date());
        configRelation.setUpdateTime(new Date());

        configRelationDao.saveSelective(configRelation);

        return config;
    }

    private void checkAdd(Config config, String zuulFilterId) {
        if (!Detect.notEmpty(config.getName()) || !Detect.notEmpty(config.getValue())
                || !Detect.notEmpty(config.getComment()) || !Detect.notEmpty(config.getApplicationName())
                || !Detect.notEmpty(zuulFilterId)) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
//        if (!config.getName().startsWith("_zuul.config.")) {
//            throw new HomedoException("[配置名必须以“_zuul.config.”开头]");
//        }
    }
}
